// 工厂方法类
public abstract class FactoryMethod {
	// 测试函数
	public static void main(String[] args) {
		// 根据用户提供的参数, 先选择子类工厂, 再由子类工厂创建具体的子类产品
		System.out.println(FactoryMethod.chooseFactory("A").getProduct());
		System.out.println(FactoryMethod.chooseFactory("B").getProduct());
	}

	// 静态方法, 根据参数实例化具体子类工厂
	// 注意和简单工厂的区别, 简单工厂直接创建子类产品
	// 而工厂方法则是先创建下一级的子类工厂, 再由子类工厂去创建子类产品
	public static FactoryMethod chooseFactory(String factoryName) {
		// 这里的参数代表的子类工厂, 不是产品
		switch (factoryName) {
		case "A":
			return new FactoryA(); // 返回子类工厂A
		case "B":
			return new FactoryB(); // 返回子类工厂B
		default:
			return null; // 注意有可能引发空指针异常
		}
	}

	// 抽象方法, 获取具体子类产品, 由子类工厂实现该方法
	public abstract Product getProduct();
}

// 子类工厂A
class FactoryA extends FactoryMethod {
	// 重写父类工厂的抽象方法, 获取具体子类产品
	@Override
	public Product getProduct() {
		return new ProductA();
	}
}

// 子类工厂B
class FactoryB extends FactoryMethod {
	// 重写父类工厂的抽象方法, 获取具体子类产品
	// 不同的工厂, 创建的子类产品不同, 但是所有的产品都具备相同的父类外观 Product 类型
	@Override
	public Product getProduct() {
		return new ProductB();
	}
}

// 父类产品
class Product {
}

// 子类产品A
class ProductA extends Product {
}

// 子类产品B
class ProductB extends Product {
}